package com.tiancheng.trade.order.controller.api;

import com.tiancheng.trade.commom.core.data.PageInfo;
import com.tiancheng.trade.commom.core.data.Result;
import com.tiancheng.trade.commom.core.enums.PaymentChannelEnum;
import com.tiancheng.trade.commom.core.exception.error.BusinessErrorInfoEnum;
import com.tiancheng.trade.commom.core.utils.JsonUtil;
import com.tiancheng.trade.commom.core.utils.DateTimeUtil;
import com.tiancheng.trade.order.bo.CouponBO;
import com.tiancheng.trade.order.bo.OrderBO;
import com.tiancheng.trade.order.bo.SubOrderBO;
import com.tiancheng.trade.order.bo.VipBO;
import com.tiancheng.trade.order.bo.cmq.ScrmOrder;
import com.tiancheng.trade.order.bo.cmq.VipMsgBO;
import com.tiancheng.trade.order.enums.*;
import com.tiancheng.trade.order.model.Order;
import com.tiancheng.trade.order.service.*;
import com.tiancheng.trade.order.util.*;
import com.tiancheng.trade.order.util.cmq.queue.producer.VipMessageProducer;
import com.tiancheng.trade.order.util.helper.OrderIdHelper;
import com.tiancheng.trade.order.vo.api.*;
import com.tiancheng.trade.order.vo.api.res.CreateOrderResVO;
import com.tiancheng.trade.order.vo.api.res.OrderDiscountInfoVO;
import com.tiancheng.trade.order.vo.app.res.VipCheckResVO;
import com.tiancheng.trade.order.vo.parallel.AppleInAppPayVO;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单业务侧api接口
 *
 * @author kellen
 * @date 2024-03-02
 */
@RestController
@RequestMapping("/api")
@Validated
@Slf4j
public class OrderApiController {

    @Resource
    private OrderService orderService;
    @Resource
    private OrderIdHelper orderIdHelper;
    @Resource
    private CouponService couponService;
    @Resource
    private SubOrderService subOrderService;
    @Resource
    private IntOrderService intOrderService;
    @Resource
    private VipSystemService vipSystemService;
    @Resource
    private VipMessageProducer vipMessageProducer;
    @Resource
    private OrderBatchService orderBatchService;

    /**
     * 获取主订单号
     *
     * @param orderScene
     * @param orderSource
     * @param subOrderNum
     * @return
     */
    @GetMapping(value = "/sn")
    public Result sn(@RequestParam("order_scene") @NotEmpty String orderScene, @RequestParam("uid") @NotEmpty String uid,
                     @RequestParam("order_source") @NotEmpty String orderSource, @RequestParam("sub_order_num") @NotNull Integer subOrderNum,
                     @RequestParam("is_test") @NotNull Boolean isTest) {
        OrderSourceEnum orderSourceEnum = EnumUtil.getEnumByCode(OrderSourceEnum.class, orderSource);
        BusinessErrorInfoEnum.ORDER_CREATE_SOURCE.assertNotNull(orderSourceEnum);

        String orderId = orderIdHelper.get(orderScene, orderSource, uid, isTest);
        List<String> subOrderIds = orderIdHelper.getSub(orderId, subOrderNum);
        Map<String, Object> result = new HashMap<>();
        result.put("order_id", orderId);
        result.put("sub_order_id_list", subOrderIds);
        return Result.success(result);
    }

    @GetMapping(value = "/orderBatchSn")
    public Result OrderBatchSn(@RequestParam("uid") @NotEmpty String uid,
                     @RequestParam("order_source") @NotEmpty String orderSource, @RequestParam("order_num") @NotNull Integer orderNum) {
        OrderSourceEnum orderSourceEnum = EnumUtil.getEnumByCode(OrderSourceEnum.class, orderSource);
        BusinessErrorInfoEnum.ORDER_CREATE_SOURCE.assertNotNull(orderSourceEnum);

        final String batchOrderId = orderIdHelper.getBatchOrderId(uid,orderNum);
        Map<String, Object> result = new HashMap<>();
        result.put("batch_id", batchOrderId);
        return Result.success(result);
    }


    @PostMapping(value = "/createOrderBatch", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Result createOrderBatch(@RequestBody @Valid OrderBatchVO orderBatchVO) {
        OrderSourceEnum orderSourceEnum = EnumUtil.getEnumByCode(OrderSourceEnum.class, orderBatchVO.getOrderSource());
        BusinessErrorInfoEnum.ORDER_CREATE_SOURCE.assertNotNull(orderSourceEnum);
        orderBatchService.saveOrderBatch(orderBatchVO,orderService.findByUidAndBatchId(orderBatchVO.getUid(),orderBatchVO.getBatchId()));
        return Result.success();
    }

    /**
     * 创建订单
     *
     * @param orderVO
     * @return
     */
    @PostMapping(value = "/create", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Result create(@RequestBody @Valid OrderVO orderVO) {
        // 生成主订单业务对象
        OrderBO orderBO = this.toOrderBO(orderVO);
        if (StringUtils.isEmpty(orderBO.getSystemSource())) {
            orderBO.setSystemSource(SystemSourceEnum.YOUYUNNAN.getCode());
        }
        if (StringUtils.isEmpty(orderBO.getBusinessType())) {
            orderBO.setBusinessType(BusinessTypeEnum.B2C.getCode());
        }
        // 生成子订单业务对象列表
        List<SubOrderBO> subOrderBOS = this.toSubOrderBO(orderVO);
        if(orderVO.getOrderType().equals(OrderTypeEnum.deduction.getCode())){
            BusinessErrorInfoEnum.ORDER_VIP_DISCOUNT_COMPOSITION_ERROR.assertIsTrue(CollectionUtils.isEmpty(orderVO.getCoupons()) &&
                    (null == orderVO.getVipInfo() || ((orderVO.getVipInfo().getDiscount() == null || orderVO.getVipInfo().getDiscount() ==0 ||
                            orderVO.getVipInfo().getDiscount() == 100)
                            || (orderVO.getVipInfo().getUseBeam() == null || orderVO.getVipInfo().getUseBeam() == 0))));
            // 零元抵扣订单逻辑
            orderBO.setPayChannel(orderService.getPayChannelAndSetMerchant(subOrderBOS, orderVO));
            // 零元抵扣只支持银联渠道
            BusinessErrorInfoEnum.ORDER_CREATE_CHANNEL_ERROR.assertIsTrue(orderBO.getPayChannel().equals(PaymentChannelEnum.UMS.getCode()));
            // 创建订单
            String orderId = orderService.createDeductionOrder(orderBO, subOrderBOS);
            return Result.success(orderId);
        }
        if (orderVO.getOrderBusiness() != null && "overseas".equals(orderVO.getOrderBusiness())) {//判断是否走英文版支付流程
            try {
                // 支付渠道 : 英文版目前只有PayPal
                orderBO.setPayChannel(PaymentChannelEnum.PAYPAL.getCode());
                String orderId = intOrderService.create(orderBO, subOrderBOS);
                return Result.success(orderId);
            } catch (Exception e) {
                throw e;
            }
        } else {
            // 计算会员折扣金额
            final int vipDiscount = this.getVipDiscount(orderVO);
            // 生成优惠券业务对象
            List<CouponBO> couponBOS = this.toCouponBO(orderVO, vipDiscount);

            // 锁定优惠券信息
            List<CouponBO> lockedCoupons = couponService.lock(couponBOS);
            Result<VipBO> vipBOResult = null;
            // 会员优惠
            try {
                // 获取支付渠道
                // 20210120 调整
                orderBO.setPayChannel(orderService.getPayChannelAndSetMerchant(subOrderBOS, orderVO));
                // 会员权益校验
                vipBOResult = vipCheck(orderVO, vipDiscount, lockedCoupons);
                BusinessErrorInfoEnum.ORDER_VIP_CHECK_ERROR.assertIsTrue(vipBOResult.getRet() == 0);
                String orderId = orderService.create(orderBO, subOrderBOS, lockedCoupons, vipBOResult.getData());
                return Result.success(orderId);
            } catch (Exception e) {
                if (vipBOResult != null && vipBOResult.getRet() == 0 && vipBOResult.getData() != null) {
                    // 发送取消消息
                    VipMsgBO vipMsgBO = new VipMsgBO();
                    vipMsgBO.setUid(orderVO.getUid());
                    vipMsgBO.setType("consumption");
                    vipMsgBO.setAction(VipMessageProducer.ACTION_CANCEL);
                    vipMsgBO.setScene(orderBO.getOrderSource());
                    vipMsgBO.setTime(DateTimeUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
                    Map<String, Object> orderMap = new HashMap<>();
                    orderMap.put("order_id", orderVO.getOrderId());
                    final List<Map<String, Object>> subOrders = new ArrayList<>(subOrderBOS.size());
                    for (SubOrderBO s : subOrderBOS) {
                        final VipBO.SubOrder so = vipBOResult.getData().getSubOrders().stream().filter(o -> o.getSubOrderId().equals(s.getSubOrderId())).findFirst().get();
                        Map<String, Object> subOrder = new HashMap<>();
                        subOrder.put("sub_order_id", s.getSubOrderId());
                        subOrder.put("amount", s.getSubOrderAmount() - s.getPlatformDiscount() - so.getDiscountAmount() - so.getUseBeamAmount());
                        subOrders.add(subOrder);
                    }
                    orderMap.put("list", subOrders);
                    vipMsgBO.setExtend(orderMap);
                    log.info("创建订单失败，释放锁定的会员权益:{}", JsonUtil.toJsonString(vipMsgBO));
                    final boolean sec = vipMessageProducer.sendVipMsg(vipMsgBO);
                    if (!sec) {
                        vipMessageProducer.sendVipMsg(vipMsgBO);
                    }
                }
                // 创建订单失败，解锁之前的优惠券
                couponService.unlock(lockedCoupons);
                throw e;
            }
        }
    }

    private Result<VipBO> vipCheck(OrderVO orderVO, int vipDiscount, List<CouponBO> lockedCoupons) {
        if (null != orderVO.getVipInfo() && ((orderVO.getVipInfo().getDiscount() != null && orderVO.getVipInfo().getDiscount() > 0 &&
                orderVO.getVipInfo().getDiscount() < 100)
                || (orderVO.getVipInfo().getUseBeam() != null && orderVO.getVipInfo().getUseBeam() > 0))) {
            final VipBO vipBO = new VipBO();
            vipBO.setDiscount(null == orderVO.getVipInfo().getDiscount() ? 0 : orderVO.getVipInfo().getDiscount());
            vipBO.setOrderId(orderVO.getOrderId());
            // 优惠金额
            int couponAmount = 0;
            if (!CollectionUtils.isEmpty(lockedCoupons)) {
                couponAmount = lockedCoupons.stream().mapToInt(CouponBO::getDiscount).sum();
            }
            vipBO.setDiscountAmount(vipDiscount);
            vipBO.setOrderAmount(orderVO.getSubOrders().stream().mapToInt(SubOrderVO::getSubOrderAmount).sum() - vipDiscount - couponAmount);
            vipBO.setOrderSource(orderVO.getOrderSource());
            vipBO.setUid(orderVO.getUid());
            vipBO.setUseBeam(null == orderVO.getVipInfo().getUseBeam() ? 0 : orderVO.getVipInfo().getUseBeam());
            final List<VipBO.Product> products = new ArrayList<>();
            if (!CollectionUtils.isEmpty(orderVO.getSubOrders())) {
                orderVO.getSubOrders().forEach(s -> products.add(new VipBO.Product(s.getProductCode(), s.getProductName())));
            }
            vipBO.setProductList(products);
            final Result<VipCheckResVO> vipCheckResVOResult = vipSystemService.useBeamCheck(vipBO);
            if (vipCheckResVOResult.getRet() != 0) {
                // 会员折扣与提交的不一致，返回给客户端标识
                BusinessErrorInfoEnum.ORDER_VIP_DISCOUNT_ERROR.assertIsTrue(!vipCheckResVOResult.getErrorCode().equals(61002));
                return Result.fail(vipCheckResVOResult.getMsg(), null);
            }
            vipBO.setUseBeamAmount(vipCheckResVOResult.getData().getBeanReduceAmount() == null ? 0 : vipCheckResVOResult.getData().getBeanReduceAmount());
            vipBO.setLevel(StringUtils.isEmpty(vipCheckResVOResult.getData().getLevel()) ? "" : vipCheckResVOResult.getData().getLevel());
            final List<VipBO.SubOrder> vipEquities = new ArrayList<>();
            final int sumOrderAmount = orderVO.getSubOrders().stream().mapToInt(SubOrderVO::getSubOrderAmount).sum();
            if (vipBO.getDiscountAmount() != null && vipBO.getDiscountAmount() > 0) {
                for (int i = 0; i < orderVO.getSubOrders().size(); i++) {
                    final SubOrderVO subOrderVO = orderVO.getSubOrders().get(i);
                    VipBO.SubOrder vipEquity = new VipBO.SubOrder();
                    vipEquity.setSubOrderId(subOrderVO.getSubOrderId());
                    vipEquity.setDiscount(vipBO.getDiscount());
                    vipEquity.setOrderAmount(subOrderVO.getSubOrderAmount());
                    vipEquity.setUseBeam(0);
                    vipEquity.setUseBeamAmount(0);
                    if (i == orderVO.getSubOrders().size() - 1) {
                        vipEquity.setDiscountAmount(vipBO.getDiscountAmount() - vipEquities.stream().mapToInt(VipBO.SubOrder::getDiscountAmount).sum());
                    } else {
                        int divide = BigDecimal.valueOf(subOrderVO.getSubOrderAmount()).
                                divide(BigDecimal.valueOf(sumOrderAmount), 10, BigDecimal.ROUND_DOWN)
                                .multiply(BigDecimal.valueOf(vipBO.getDiscountAmount())).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
                        vipEquity.setDiscountAmount(divide);
                    }

                    vipEquities.add(vipEquity);
                }
            }
            boolean hasDiscount = vipEquities.size() > 0;
            if (vipBO.getUseBeamAmount() != null && vipBO.getUseBeamAmount() > 0) {
                for (int i = 0; i < orderVO.getSubOrders().size(); i++) {
                    final SubOrderVO subOrderVO = orderVO.getSubOrders().get(i);
                    VipBO.SubOrder vipEquity = new VipBO.SubOrder();
                    vipEquity.setSubOrderId(subOrderVO.getSubOrderId());
                    vipEquity.setDiscount(vipBO.getDiscount());
                    vipEquity.setDiscountAmount(0);
                    vipEquity.setOrderAmount(subOrderVO.getSubOrderAmount());
                    for (int k = 0; k < vipEquities.size(); k++) {
                        if (vipEquities.get(k).getSubOrderId().equals(subOrderVO.getSubOrderId())) {
                            vipEquity = vipEquities.get(k);
                        }
                    }
                    if (i == orderVO.getSubOrders().size() - 1) {
                        vipEquity.setUseBeamAmount(vipBO.getUseBeamAmount() - vipEquities.stream().mapToInt(VipBO.SubOrder::getUseBeamAmount).sum());
                        vipEquity.setUseBeam(vipBO.getUseBeam() - vipEquities.stream().mapToInt(VipBO.SubOrder::getUseBeam).sum());
                    } else {
                        int UseBeamAmountDivide = BigDecimal.valueOf(subOrderVO.getSubOrderAmount()).
                                divide(BigDecimal.valueOf(sumOrderAmount), 10, BigDecimal.ROUND_DOWN)
                                .multiply(BigDecimal.valueOf(vipBO.getUseBeamAmount())).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
                        int UseBeamDivide = BigDecimal.valueOf(subOrderVO.getSubOrderAmount()).
                                divide(BigDecimal.valueOf(sumOrderAmount), 10, BigDecimal.ROUND_DOWN)
                                .multiply(BigDecimal.valueOf(vipBO.getUseBeam())).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
                        vipEquity.setUseBeamAmount(UseBeamAmountDivide);
                        vipEquity.setUseBeam(UseBeamDivide);
                    }
                    if (!hasDiscount) {
                        vipEquities.add(vipEquity);
                    }
                }
            }
            vipBO.setSubOrders(vipEquities);
            return Result.success(vipBO);
        }
        return Result.success(null);
    }

    /**
     * 创建订单(封装返回信息)
     *
     * @param orderVO
     * @return
     */
    @PostMapping(value = "/createOrder", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Result createOrder(@RequestBody @Valid OrderVO orderVO) {
        // 生成主订单业务对象
        OrderBO orderBO = this.toOrderBO(orderVO);
        if (StringUtils.isEmpty(orderBO.getSystemSource())) {
            orderBO.setSystemSource(SystemSourceEnum.YOUYUNNAN.getCode());
        }
        if (StringUtils.isEmpty(orderBO.getBusinessType())) {
            orderBO.setBusinessType(BusinessTypeEnum.B2C.getCode());
        }
        // 生成子订单业务对象列表
        List<SubOrderBO> subOrderBOS = this.toSubOrderBO(orderVO);
        if(orderVO.getOrderType().equals(OrderTypeEnum.deduction.getCode())){
            BusinessErrorInfoEnum.ORDER_VIP_DISCOUNT_COMPOSITION_ERROR.assertIsTrue(CollectionUtils.isEmpty(orderVO.getCoupons()) &&
                    (null == orderVO.getVipInfo() || ((orderVO.getVipInfo().getDiscount() == null || orderVO.getVipInfo().getDiscount() ==0 ||
                            orderVO.getVipInfo().getDiscount() == 100)
                            || (orderVO.getVipInfo().getUseBeam() == null || orderVO.getVipInfo().getUseBeam() == 0))));
            // 零元抵扣订单逻辑
            orderBO.setPayChannel(orderService.getPayChannelAndSetMerchant(subOrderBOS, orderVO));
            // 零元抵扣只支持银联渠道
            BusinessErrorInfoEnum.ORDER_CREATE_CHANNEL_ERROR.assertIsTrue(orderBO.getPayChannel().equals(PaymentChannelEnum.UMS.getCode()));
            // 创建订单
            String orderId = orderService.createDeductionOrder(orderBO, subOrderBOS);
            return Result.success(orderId);
        }
        if (orderVO.getOrderBusiness() != null && "overseas".equals(orderVO.getOrderBusiness())) {//判断是否走英文版支付流程
            try {
                // 支付渠道 : 英文版目前只有PayPal
                orderBO.setPayChannel(PaymentChannelEnum.PAYPAL.getCode());
                log.info("判断版本信息 客户端：{} 传入版本号：{} 版本支付渠道结果-->>{}", orderVO.getAppType(), orderVO.getAppVersion(), orderBO.getPayChannel());
                CreateOrderResVO createOrderResVO = intOrderService.createOrder(orderBO, subOrderBOS);
                return Result.success(createOrderResVO);
            } catch (Exception e) {
                throw e;
            }
        } else {
            // 计算会员折扣金额
            final int vipDiscount = this.getVipDiscount(orderVO);
            // 生成优惠券业务对象
            List<CouponBO> couponBOS = this.toCouponBO(orderVO, vipDiscount);

            // 锁定优惠券信息
            List<CouponBO> lockedCoupons = couponService.lock(couponBOS);
            Result<VipBO> vipBOResult = null;
            try {
                // 获取支付渠道
                // 20210120 调整
                orderBO.setPayChannel(orderService.getPayChannelAndSetMerchant(subOrderBOS, orderVO));
                // 会员权益校验
                vipBOResult = vipCheck(orderVO, vipDiscount, lockedCoupons);
                BusinessErrorInfoEnum.ORDER_VIP_CHECK_ERROR.assertIsTrue(vipBOResult.getRet() == 0);
                CreateOrderResVO createOrderResVO = orderService.createOrder(orderBO, subOrderBOS, lockedCoupons, vipBOResult.getData());
                return Result.success(createOrderResVO);
            } catch (Exception e) {
                if (vipBOResult != null && vipBOResult.getRet() == 0 && vipBOResult.getData() != null) {
                    int totalDiscount = vipDiscount + vipBOResult.getData().getUseBeamAmount();
                    if (lockedCoupons.size() > 0) {
                        totalDiscount += lockedCoupons.stream().mapToInt(CouponBO::getDiscount).sum();
                    }
                    // 发送取消消息
                    VipMsgBO vipMsgBO = new VipMsgBO();
                    vipMsgBO.setUid(orderVO.getUid());
                    vipMsgBO.setType("consumption");
                    vipMsgBO.setAction(VipMessageProducer.ACTION_CANCEL);
                    vipMsgBO.setScene(orderBO.getOrderSource());
                    vipMsgBO.setTime(DateTimeUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
                    Map<String, Object> orderMap = new HashMap<>();
                    orderMap.put("order_id", orderVO.getOrderId());
                    final List<Map<String, Object>> subOrders = new ArrayList<>(subOrderBOS.size());
                    for (SubOrderBO s : subOrderBOS) {
                        final VipBO.SubOrder so = vipBOResult.getData().getSubOrders().stream().filter(o -> o.getSubOrderId().equals(s.getSubOrderId())).findFirst().get();
                        Map<String, Object> subOrder = new HashMap<>();
                        subOrder.put("sub_order_id", s.getSubOrderId());
                        subOrder.put("amount", s.getSubOrderAmount() - s.getPlatformDiscount() - so.getDiscountAmount() - so.getUseBeamAmount());
                        subOrders.add(subOrder);
                    }
                    orderMap.put("list", subOrders);
                    vipMsgBO.setExtend(orderMap);
                    log.info("创建订单失败，释放锁定的会员权益:{}", JsonUtil.toJsonString(vipMsgBO));
                    final boolean sec = vipMessageProducer.sendVipMsg(vipMsgBO);
                    if (!sec) {
                        vipMessageProducer.sendVipMsg(vipMsgBO);
                    }
                }
                // 创建订单失败，解锁之前的优惠券
                couponService.unlock(lockedCoupons);
                throw e;
            }
        }
    }

    /**
     * 根据订单号查询
     *
     * @param uid
     * @param orderId
     * @return
     */
    @GetMapping("/get")
    public Result get(@RequestParam("order_id") @NotEmpty String orderId, @RequestParam("uid") @NotEmpty String uid) {
        Order order = orderService.get(uid, orderId);
        Map<String, Object> res = JsonUtil.fromJson(JsonUtil.toJsonString(order), Map.class);
        res.put("pay_left_second", Duration.between(LocalDateTime.now(), order.getPayExpiryTime()).toMillis() / 1000);
        return Result.success(res);
    }

    /**
     * 计算折扣金额
     *
     * @return
     */
    private int getVipDiscount(OrderVO orderVO) {
        if (null != orderVO.getVipInfo() && orderVO.getVipInfo().getDiscount() != null && orderVO.getVipInfo().getDiscount() > 0 && orderVO.getVipInfo().getDiscount() < 100) {
            int totalAmount = orderVO.getSubOrders().stream().mapToInt(SubOrderVO::getSubOrderAmount).sum();
            final int orderAmount = new BigDecimal(totalAmount).multiply(
                    new BigDecimal(orderVO.getVipInfo().getDiscount()).divide(new BigDecimal(100))
            ).setScale(0, RoundingMode.HALF_UP).intValue();
            return totalAmount - orderAmount;
        }
        return 0;
    }

    /**
     * 参数转成主订单业务对象
     *
     * @param orderVO
     * @return
     */
    private OrderBO toOrderBO(OrderVO orderVO) {
        OrderBO orderBO = ObjectConvertUtil.convert(orderVO, OrderBO.class).get();
        orderBO.setIsTest(Objects.isNull(orderVO)?0:1);
        orderBO.setOrderAmount(orderVO.getSubOrders().stream().mapToInt(SubOrderVO::getSubOrderAmount).sum());
        orderBO.setIsCoupon(org.apache.commons.collections4.CollectionUtils.isNotEmpty(orderVO.getCoupons())?1:0);
        orderBO.setDiscount(0);
        orderBO.setPlatformDiscount(0);
        if (StringUtils.isEmpty(orderBO.getOriginalOrderId())) {
            orderBO.setOriginalOrderId("0");
        }

        // 默认使用第一笔子订单的商品名称作为订单名称
        if (StringUtils.isEmpty(orderBO.getOrderName())) {
            orderBO.setOrderName(orderVO.getSubOrders().get(0).getProductName());
        }
        // 对orderName进行制表符、换行符、前后空格处理
        orderBO.setOrderName(CommonUtil.trim(orderBO.getOrderName()));
        return orderBO;
    }

    /**
     * 参数转成子订单业务对象
     *
     * @param orderVO
     * @return
     */
    private List<SubOrderBO> toSubOrderBO(OrderVO orderVO) {
        List<SubOrderBO> subOrderBOS = orderVO.getSubOrders().stream().map(subOrderVO -> {
            SubOrderBO subOrderBO = ObjectConvertUtil.convert(subOrderVO, SubOrderBO.class).get();
            subOrderBO.setOrderId(orderVO.getOrderId());
            subOrderBO.setOrderSource(orderVO.getOrderSource());
            subOrderBO.setCreateTime(orderVO.getCreateTime());
            subOrderBO.setIsCoupon(subOrderVO.getCoupons() != null && subOrderVO.getCoupons().size() > 0?1:0);
            subOrderBO.setDiscount(0);    //初始化
            subOrderBO.setPlatformDiscount(0);
            // 对名称进行制表符、换行符、前后空格处理
            subOrderBO.setProductName(CommonUtil.trim(subOrderBO.getProductName()));
            subOrderBO.setProductDetail(CommonUtil.trim(subOrderBO.getProductDetail()));
            if (StringUtils.isEmpty(subOrderBO.getOriginalSubOrderId())) {
                subOrderBO.setOriginalSubOrderId("0");
            }
            return subOrderBO;
        }).collect(Collectors.toList());
        return subOrderBOS;
    }

    /**
     * 参数转成优惠券对象（目前只支持平台单张优惠）
     *
     * @param orderVO
     * @param vipDiscount 会员折扣金额
     * @return
     */
    private List<CouponBO> toCouponBO(OrderVO orderVO, int vipDiscount) {
        List<CouponBO> couponBOS = new ArrayList<>();
        if (orderVO.getCoupons() != null && orderVO.getCoupons().size() > 0) {
            couponBOS.addAll(orderVO.getCoupons().stream().map(couponVO -> {
                CouponBO couponBO = new CouponBO();
                couponBO.setCouponCode(couponVO.getCodeId());
                couponBO.setOrderId(orderVO.getOrderId());
                couponBO.setAmount(orderVO.getSubOrders().stream().mapToInt(SubOrderVO::getSubOrderAmount).sum() - vipDiscount);
                couponBO.setProductCode(orderVO.getSubOrders().get(0).getProductCode());
                couponBO.setDiscountSource(orderVO.getOrderSource());
                couponBO.setUid(orderVO.getUid());
                return couponBO;
            }).collect(Collectors.toList()));
        }
        return couponBOS;
    }

    /**
     * 功能描述: 关闭订单
     * 1、更新订单状态
     * 2、
     *
     * @param: 流水号：flowId,用户id：userId
     * @return:
     * @auther: LiuDong
     * @date: 13:50 2024/3/6
     */
    @PostMapping("/close")
    public Result closeOrder(@RequestBody @Valid CloseOrderVO closeOrderVO) {
        boolean result = false;
        if (closeOrderVO.getOrderBusiness() != null && "overseas".equals(closeOrderVO.getOrderBusiness())) {//判断是否走英文版订单流程
            result = intOrderService.closeOrder(closeOrderVO);
        } else {
            result = orderService.closeOrder(closeOrderVO);
        }
        if (result) {
            return Result.success();
        } else {
            return Result.fail("关闭失败");
        }
    }


    /**
     * 功能描述: 关闭批次订单
     * 1、更新订单状态
     * 2、
     *
     * @param: 流水号：flowId,用户id：userId
     * @return:
     * @auther: LiuDong
     * @date: 13:50 2024/3/6
     */
    @PostMapping("/closeBatchOrder")
    public Result closeOrder(@RequestBody @Valid CloseOrderBatchVO orderBatchVO) {
        boolean result = orderBatchService.close(orderBatchVO.getUid(),orderBatchVO.getBatchId());
        if (result) {
            return Result.success();
        } else {
            return Result.fail("关闭失败");
        }
    }



    /**
     * 修改订单信息
     *
     * @param updateOrderVO
     * @return
     */
    @RequestMapping(value = "/update", method = {RequestMethod.POST, RequestMethod.PATCH}, consumes = MediaType.APPLICATION_JSON_VALUE)
    public Result update(@RequestBody @Valid UpdateOrderVO updateOrderVO) {
        orderService.updateAmount(updateOrderVO);
        return Result.success();
    }

    /**
     * 查询指定子订单
     *
     * @param subOrderId
     * @return
     */
    @GetMapping("/sub/{subOrderId}")
    public Result getSubOrder(@PathVariable String subOrderId) {
        return Result.success(subOrderService.getWithJoin(subOrderId));
    }

    /**
     * 根据支付流水号查询主订单及子订单数据
     *
     * @param flowId
     * @return
     */
    @GetMapping("/sub/findByFlowId")
    public Result findSubOrderByFlowId(@RequestParam("flow_id") String flowId) {
        return Result.success(orderService.findWithSubByFlowId(flowId));
    }

    /**
     * 根据订单号查号询主订单及子订单数据
     *
     * @param orderId
     * @return
     */
    @GetMapping("/sub/findByOrderId")
    public Result findByOrderId(@RequestParam("order_id") String orderId) {
        return Result.success(orderService.findByOrderId(orderId));
    }

    /**
     * 按月查询子订单信息
     *
     * @return
     */
    @GetMapping("/sub/findSubOrderByDate")
    public Result findSubOrderByDate(@RequestParam("date") String date) {
        return Result.success(subOrderService.findSubOrderByDate(date));
    }

    /**
     * 核销订单
     *
     * @return
     */
    @PostMapping("/verification")
    public Result verification(@RequestBody VerificationOrderVO date) {
        return Result.success(subOrderService.verification(date));
    }

    /**
     * 订单状态上报
     *
     * @return
     */
    @PostMapping("/reportOrderStatus")
    public Result reportOrderStatus(@RequestBody @Valid ReportOrderStatusVO date) {
        subOrderService.reportOrderStatus(date);
        return Result.success();
    }


    /**
     * 苹果支付
     *
     * @param appleInAppPayVO
     * @return
     */
    @PostMapping(value = "/appleInAppPay", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Result appleInAppPay(@RequestBody @Valid AppleInAppPayVO appleInAppPayVO) {
        return Result.success(orderService.appleInAppPayNew(appleInAppPayVO));
    }

    @PostMapping(value = "/getScrmPayOrder")
    public Result queryPayOrderAndSubOrder(@RequestBody @Valid ScrmOrderQueryVO queryVO) {
        final PageInfo<ScrmOrder> scrmOrderPageInfo = orderService.queryPayOrderAndSubOrder(queryVO);
        return Result.success(scrmOrderPageInfo);
    }

    @GetMapping(value = "/getOrderDiscountInfo")
    public Result<OrderDiscountInfoVO> getOrderDiscountInfo(@RequestParam("order_id") String orderId) {
        final OrderDiscountInfoVO orderDiscountInfoVO = orderService.getOrderDiscountInfo(orderId);
        return Result.success(orderDiscountInfoVO);
    }

}
